package com.hefeng.wx.crawler;

import com.hefeng.wx.constant.Code;
import com.hefeng.wx.domain.entity.AreaCodeEntity;
import com.hefeng.wx.domain.entity.CityCodeEntity;
import com.hefeng.wx.domain.entity.ProvinceCodeEntity;
import com.hefeng.wx.domain.entity.StreetCodeEntity;
import com.hefeng.wx.service.SysAreasService;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * 组织机构获取类
 */

public class GetZoningCode {
    static private GetZoningCode zoningCode;
    @Autowired
    SysAreasService sysAreasService;
    /** 关注这个对象就好
     * 此对象为数据写入源
     * 层级关系已经整理好了
     * **/
    private List<ProvinceCodeEntity> provinceCodeEntities;
    List cttyList=new ArrayList();

    /**
     * TODO 程序入口
     * @param args
     */

    public static void main(String[] args) {
        System.out.println(String.format("%s%s%s", Code.SPLIT_STR_START, "开始", Code.SPLIT_STR_END));
        zoningCode = new GetZoningCode();
        zoningCode.provinceCodeEntities = new ArrayList<>();
        zoningCode.startCrawling();
        System.out.println(zoningCode.provinceCodeEntities.toString());
    }


    public List<ProvinceCodeEntity> seveAeras(){
       zoningCode = new GetZoningCode();
        zoningCode.provinceCodeEntities = new ArrayList<>();
        zoningCode.startCrawling();
        return zoningCode.provinceCodeEntities;

    }
    /**
     * TODO 获取省级Url
     */
    public void startCrawling() {
        try {

            // 获取省、直辖市code
            getProvinceUrls();

            // 获取市、直辖市内区code
            getCityUrls();

            // 获取区、直辖市街道code
            getAreaUrls();

            // 获取街道code
            getStreetUrls();
            System.out.println(String.format("%s%s%s", Code.SPLIT_STR_START, "结束", Code.SPLIT_STR_END));

           /* provinceCodeEntities.forEach(stu->{
                SysAreas areas=new SysAreas();
                areas.setCode(stu.getProvinceCode());
                areas.setPCode(stu.getProvinceCode());
                areas.setName(stu.getProvinceName());
                areas.setLevel(1);
                sysAreasService.seve(areas);
            });*/

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * TODO 获取doc对象
     *
     * @param url
     * @return
     * @throws Exception
     */
    private Document getDoc(String url) throws Exception {
        Connection connection = Jsoup.connect(url);

        connection.userAgent(Code.BASE_UA);
        connection.timeout(Code.TIME_OUT);
        Document document = connection.get();
        return document;
    }

    /**
     * TODO 获取各省、直辖市url
     *
     * @return
     * @throws Exception
     */
    private void getProvinceUrls() throws Exception {
        Elements links = getEleLinks(getDoc(String.format("%s%s", Code.BASE_URL, Code.INDEX)));

        for (Element link : links) {
            ProvinceCodeEntity provinceCode = new ProvinceCodeEntity();
            if (link.text().indexOf(Code.TARGET_NAME) > -1) {
                provinceCode.setProvinceName(link.text());
                provinceCode.setProvinceCode(link.attr("href").replaceAll(".html", ""));
                provinceCode.setUrl(String.format("%s%s", Code.BASE_URL, link.attr("href")));
                provinceCodeEntities.add(provinceCode);
            }
        }
    }

    /**
     * TODO 获取统一属性条件的链接对象
     *
     * @param document
     * @return
     */
    private Elements getEleLinks(Document document) {
        Element body = document.body();
        Elements coreTd = body.getElementsByAttributeValue("style", Code.BASE_STYLE_STR);
        Elements links = coreTd.select("a[href]");

        return links;
    }

    /**
     * TODO 获取统一属性条件的链接对象
     *
     * @param
     */
    private void getEleLinks4p(ProvinceCodeEntity province) throws Exception {
        Element body = getDoc(province.getUrl()).body();
        Elements coreTd = body.getElementsByAttributeValue("style", Code.BASE_STYLE_STR);

        if (coreTd.size() == 1) {
            coreTd = coreTd.get(0).getElementsByAttributeValue("class", "citytr");
        }

        province.setCityCodeEntities(new ArrayList<>());

        for (Element element : coreTd) {
            CityCodeEntity cityCode = new CityCodeEntity();
            Elements tr = element.select("td");
            if (tr.size() == 2) {
                cityCode.setCityCode(tr.get(0).select("a[href]").text());
                cityCode.setCityName(tr.get(1).select("a[href]").text());
                cityCode.setUrl(String.format("%s%s", Code.BASE_URL, tr.get(1).select("a[href]").attr("href")));
                province.getCityCodeEntities().add(cityCode);
                //System.out.println(cityCode.toString());
            }
        }
    }

    /**
     * TODO 获取统一属性条件的链接对象(区市级)
     *
     * @param
     */
    private void getEleLinks4c(CityCodeEntity city) throws Exception {
        Element body = getDoc(city.getUrl()).body();
        Elements coreTd = body.getElementsByAttributeValue("style", Code.BASE_STYLE_STR);

        if (coreTd.size() == 1) {
            coreTd = coreTd.get(0).getElementsByAttributeValue("class", "countytr");
        }

        city.setAreaCodeEntities(new ArrayList<>());

        for (Element element : coreTd) {
            AreaCodeEntity areaCode = new AreaCodeEntity();
            Elements tr = element.select("td");
            if (tr.size() == 2 && tr.get(0).select("a[href]").size() > 0) {
                areaCode.setAreaCode(tr.get(0).select("a[href]").text());
                areaCode.setAreaName(tr.get(1).select("a[href]").text());
                areaCode.setUrl(String.format("%s%s%s%s", Code.BASE_URL, city.getCityCode().substring(0, 2), "/", tr.get(1).select("a[href]").attr("href")));
                city.getAreaCodeEntities().add(areaCode);
                //System.out.println(areaCode.toString());

            }
        }
    }

    /**
     * TODO 获取统一属性条件的链接对象(区市级)
     *
     * @param
     */
    private void getEleLinks4a(AreaCodeEntity area) throws Exception {
        if (area.getUrl().indexOf(".html") > -1) {
            Element body = getDoc(area.getUrl()).body();
            Elements coreTd = body.getElementsByAttributeValue("style", Code.BASE_STYLE_STR);

            if (coreTd.size() == 1) {
                coreTd = coreTd.get(0).getElementsByAttributeValue("class", "towntr");
            }

            area.setStreetCodeEntities(new ArrayList<>());

            for (Element element : coreTd) {
                StreetCodeEntity streetCode = new StreetCodeEntity();
                Elements tr = element.select("td");
                if (tr.size() == 2) {
                    streetCode.setStreetCode(tr.get(0).select("a[href]").text());
                    streetCode.setStreetName(tr.get(1).select("a[href]").text());
                    area.getStreetCodeEntities().add(streetCode);
                    //System.out.println(streetCode.toString());

                }
            }
        }
    }

    /**
     * TODO 逐个获取城市编码及信息
     *
     * @throws Exception
     */
    private void getCityUrls() throws Exception {
        for (ProvinceCodeEntity province : provinceCodeEntities) {
            getEleLinks4p(province);
        }
    }

    /**
     * TODO 获取区域信息
     *
     * @throws Exception
     */
    private void getAreaUrls() throws Exception {
        for (ProvinceCodeEntity province : provinceCodeEntities) {
            for (CityCodeEntity city : province.getCityCodeEntities()) {
                getEleLinks4c(city);
            }
        }
    }

    /**
     * TODO 获取街道信息
     *
     * @throws Exception
     */
    private void getStreetUrls() throws Exception {
        for (ProvinceCodeEntity province : provinceCodeEntities) {
            for (CityCodeEntity city : province.getCityCodeEntities()) {
                for (AreaCodeEntity area : city.getAreaCodeEntities()) {
                    getEleLinks4a(area);
                }
            }
        }
    }
}
